package com.ht.impl;

import com.ht.aems.util.JOFileUtil;
import com.ht.impl.drawtool.DrawToolBar;
import com.ht.impl.editor.EditorPalette;
import com.ht.impl.shape.ShapeRegister;
import com.mxgraph.io.mxCodec;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGraphModel;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxGraph;
import com.htgraph.util.GraphLoader;
import org.w3c.dom.Document;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.InputStream;
import java.util.*;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @author Dong Shufeng
 *         Date: 2010-6-13
 */
public class PaletteUtil {

    private static Document styleDoc = mxUtils.loadDocument(PaletteUtil.class.getResource("/config/ht-style.xml").toString());
    private static ResourceBundle rb = ResourceBundle.getBundle("config.images");

    public static void readFile(InputStream f, EditorPalette palette, mxGraphComponent graphComponent) {
        parseXml(f, palette, graphComponent);
    }

//    public static void readFile(File f, EditorPalette palette) {
//        for (File file : f.listFiles()) {
//            if (file.getName().endsWith("mxe")) {
//                parseMxe(file, palette);
//            }
//        }
//    }

    private static void parseXml(InputStream file, EditorPalette palette, mxGraphComponent graphComponent) {
        Object object = JOFileUtil.decode4XML(file);
        if (object instanceof HashMap) {
            Map<String, Object[]> result = (Map<String, Object[]>) object;
            DrawToolBar bar = DrawToolBar.createToolBar();
            bar.setContainer(graphComponent);
            for (String s : result.keySet()) {
                Object[] obj = result.get(s);
                if (!(Boolean) obj[6])
                    palette.addTemplate(obj[0].toString(), new ImageIcon(GraphEditor.class.getResource(obj[1].toString())), obj[2] == null ? null : obj[2].toString(), Integer.parseInt(obj[3].toString()), Integer.parseInt(obj[4].toString()), obj[5].toString());
                else
                    palette.addEdgeTemplate(obj[0].toString(), new ImageIcon(GraphEditor.class.getResource(obj[1].toString())), obj[2] == null ? null : obj[2].toString(), Integer.parseInt(obj[3].toString()), Integer.parseInt(obj[4].toString()), obj[5].toString());
            }
        } else if (object instanceof List) {
            List list = (List) object;
            for (Object obj : list) {
                String fileName = obj.toString().substring(obj.toString().lastIndexOf("/") + 1);
                try {
                    parseMxe(GraphEditor.class.getResourceAsStream(obj.toString()), fileName, palette);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void parseMxe(InputStream f, String fileName, EditorPalette palette) {
        try {
            Document document = GraphLoader.parse(f);
            mxCodec codec = new mxCodec(document);
            mxGraph graph = new mxGraph(new mxGraphModel());
            codec.decode(document.getDocumentElement(), graph.getModel());
            codec.decode(styleDoc.getDocumentElement(), graph.getStylesheet());

            Object root = graph.getDefaultParent();
            Object[] cells = graph.getChildCells(root);
            //build custom style
            String style = "shape=" + ShapeRegister.SHAPE_CELLARRAY + ";";//default parent cell is not count
            int index = 0;
            Rectangle unionRect = null;
            for (Object obj : cells) {
                mxCell cell = (mxCell) obj;
                if (cell.getChildCount() > 0)
                    continue;
                String s = cell.getStyle();
                if (s == null) {
                    s = "";
                } else {
                    s = s.replace(";", "&");
                    s = s.replace("=", ":");
                    if (!s.endsWith("&"))
                        s += "&";
                }
                if (cell.isEdge()) {
                    mxPoint sourceP = cell.getGeometry().getSourcePoint();
                    mxPoint targetP = cell.getGeometry().getTargetPoint();
                    if (sourceP == null) {
                        mxCell source = (mxCell) cell.getSource();
                        sourceP = new mxPoint(source.getGeometry().getCenterX(), source.getGeometry().getCenterY());
                    }
                    if (targetP == null) {
                        mxCell target = (mxCell) cell.getTarget();
                        targetP = new mxPoint(target.getGeometry().getCenterX(), target.getGeometry().getCenterY());
                    }
                    s += ("sourceX:" + sourceP.getX() + "&");
                    s += ("sourceY:" + sourceP.getY() + "&");
                    s += ("targetX:" + targetP.getX() + "&");
                    s += ("targetY:" + targetP.getY() + "&");
                    List<mxPoint> points = cell.getGeometry().getPoints();
                    Rectangle2D r = new Rectangle2D.Double(sourceP.getX(), sourceP.getY(), 0, 0);
                    r.add(targetP.getPoint());
                    if (points != null && points.size() != 0) {
                        String pts = "htPoints:";
                        for (mxPoint p : points) {
                            pts += p.getX() + "," + p.getY() + "|";
                            r.add(p.getPoint());
                        }
                        s += pts.substring(0, pts.length() - 1);
                        s += "&";
                    }
                    s += ("x:" + r.getX() + "&");
                    s += ("y:" + r.getY() + "&");
                    s += ("w:" + r.getWidth() + "&");
                    s += ("h:" + r.getHeight()) + "&";
                    if (unionRect == null)
                        unionRect = r.getBounds();
                    else
                        unionRect.add(r.getBounds());
                } else {
                    double x = cell.getGeometry().getX();
                    s += ("x:" + x + "&");
                    double y = cell.getGeometry().getY();
                    s += ("y:" + y + "&");
                    double width = cell.getGeometry().getWidth();
                    s += ("w:" + width + "&");
                    double height = cell.getGeometry().getHeight();
                    s += ("h:" + height) + "&";
                    if (unionRect == null)
                        unionRect = cell.getGeometry().getRectangle();
                    else
                        unionRect.add(cell.getGeometry().getRectangle());
                }
                s += "isVertex:" + cell.isVertex();
                style += "cellInfo" + index + "=" + s + ";";
                index++;
            }
            style += "arraySize=" + index;
            String name = fileName.substring(0, fileName.lastIndexOf("."));
            String zh_name = rb.getString(name);
            double max = 0;
            try {
                max = (unionRect.getWidth() > unionRect.getHeight()) ? unionRect.getWidth() : unionRect.getHeight();
            } catch (Exception e) {
                e.printStackTrace();
            }
            String pictureName = name + ".png";
            ImageIcon image = new ImageIcon(GraphEditor.class.getResource("/defaultpalette/customimages/" + pictureName));
            palette.addTemplate(zh_name, image, style, unionRect.width, unionRect.height, "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}